#include "os_sal.h"


/* os mutex 互斥信号量 */


/* export func */


#if (CONFIG_OS_ENABLE == 1)

#if defined(CONFIG_OS_TYPE_FREERTOS)

#include "FreeRTOS.h"
#include "semphr.h"


/**
 * @brief OS创建互斥信号量
 * 
 * @return os_mutex_handle_t 互斥信号量句柄
 */
os_mutex_handle_t os_mutex_create(void)
{
	os_mutex_handle_t *mutex;

	mutex = (os_mutex_handle_t *)xSemaphoreCreateMutex();

	return mutex;
}

/**
 * @brief OS删除互斥信号量
 * 
 * @param mutex 互斥信号量句柄
 * @return os_status_t 
 */
os_status_t os_mutex_delete(os_mutex_handle_t mutex)
{
	vSemaphoreDelete(mutex);

	return OS_STA_SUCCESS;
}

/**
 * @brief OS获取互斥信号量(不可在中断中调用)
 * 
 * @param mutex 互斥信号量句柄
 * @param waittime 等待时间(OS_WAIT_MAX不超时等待)
 * @return os_status_t 
 */
os_status_t os_mutex_take(os_mutex_handle_t mutex, uint32_t waittime)
{
	os_status_t os_sta;
	BaseType_t err;

	if (mutex == NULL) return OS_STA_ERROR;
	if (ulPortGetIPSR() > 0) return OS_STA_SUCCESS;	// return in IRQ
	err = xSemaphoreTake((SemaphoreHandle_t)mutex, waittime);
	if (err == pdPASS) os_sta = OS_STA_SUCCESS;
	else os_sta = OS_STA_ERROR;

	return os_sta;
}

/**
 * @brief OS释放互斥信号量
 * 
 * @param mutex 互斥信号量句柄
 * @return os_status_t 
 */
os_status_t os_mutex_release(os_mutex_handle_t mutex)
{
	os_status_t os_sta;
	BaseType_t err;
	portBASE_TYPE pxHigherPriorityTaskWoken = pdFALSE;
	uint8_t isrcount;

	if (mutex == NULL) return OS_STA_ERROR; 
	isrcount = ulPortGetIPSR();
	if (isrcount > 0)
	{
		err = xSemaphoreGiveFromISR((SemaphoreHandle_t)mutex, &pxHigherPriorityTaskWoken);
		if((pdTRUE == pxHigherPriorityTaskWoken) && (1 == isrcount))
		{
			portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
		}
	}
	else
	{
		err = xSemaphoreGive((SemaphoreHandle_t)mutex);
	}

	if (err == pdPASS) os_sta = OS_STA_SUCCESS;
	else os_sta = OS_STA_ERROR;
	
	return os_sta;
}


#else
    #error "CONFIG_OS_TYPE not support!"
#endif // CONFIG_OS_TYPE

#endif // CONFIG_OS_ENABLE


